package bot;

import java.io.File;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.atomic.AtomicBoolean;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class Leg extends Thread {
	protected static final Logger LOCAL_LOG = LogManager
			.getLogger(LogManager.ROOT_LOGGER_NAME);

	private volatile boolean incoming = false;
	
	protected final AtomicBoolean turnOn=new AtomicBoolean(true);

	private final File file;

	private volatile int stepNum;

	private volatile int result;

	private volatile Head head;
	
	private final CyclicBarrier barrier;

	public Leg(String string, final CyclicBarrier barrier) {
		setName(string);
		this.barrier=barrier;
		this.file = new File("./" + getName() + ".txt");
	}

	@Override
	public void run() {
//		synchronized (this) {
//			// tells head about ready
//			notifyAll();
//		}
		try {
			this.barrier.await();
		} catch (InterruptedException e1) {
			LOCAL_LOG.error(e1.getMessage(),e1);
		} catch (BrokenBarrierException e1) {
			LOCAL_LOG.error(e1.getMessage(),e1);
		}
		while (turnOn.get()) {
			try {
				synchronized (this) {
					try {
						while (!incoming){
							LOCAL_LOG.info(getName() + " is waiting for head");
							wait();
						}
					} catch (InterruptedException e) {
						head.addException(e);
						result = -1;
						interrupt();
						break;
					}
//				try {
//					// take pause for better test in console
//					sleep(2000);
//				} catch (InterruptedException e) {
//					interrupt();
//				}
					
					if(Math.random()<0.2d)
						throw new Throwable("Oh..meet SHIT in step "+stepNum);
					if (file.exists()) {
						result = 1;
					} else {
						result = -1;
					}
				}
			} catch (Throwable e) {
				head.addException(e);
				result = -1;
			} finally {
				synchronized (this) {
					incoming = false;
					notifyAll();
				}
			}
		}
	}

	public synchronized void move(int i,Head head) {
		// synchronized (MONITOR) {
		result = 0;
		incoming = true;
		this.head = head;
		this.stepNum=i;
		notify();
		// }
	}

	public int getResult() {
		return result;
	}

}
